# 1.高阶函数
# 那么一个函数就可以接收另一个函数作为参数，这种函数就称之为高阶函数
def aa():
    print("aaa")


def bb(ags):
    ags()
    print("bbb")


funca = aa
bb(funca);


# map函数
# map()函数接收两个参数，一个是函数，一个是Iterable， map将传入的函数依次作用到序列(可迭代对象)的每个元素，并把结果作为新的Iterator迭代器返回
def f(x):
    return x * x


r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])  # 参数可迭代对象Iterable(list) 给参数传给f()
listq = list(r)
print(listq, "----map")


# filter函数
# 和map()类似，filter()也接收一个函数和一个序列。和map()不同的是，filter()把传入的函数依次作用于每个元素，
# 然后根据返回值是True还是False决定保留还是丢弃该元素
def is_odd(n):
    return n % 2 == 1


a = list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]

# sorted 排序
# 后面参数自行百度
sorted([36, 5, -12, 9, -21])
sorted([36, 5, -12, 9, -21], key=abs)
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)


# 2.返回函数
# 返回的函数在其定义内部引用了局部变量args，所以，当一个函数返回了一个函数后，其内部的局部变量还被新函数引用
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax

    return sum


f = lazy_sum(1, 2, 3)
print(f)  # 打印返回的函数
print(f())  # 打印返回的函数调用结果


# 返回闭包时牢记一点：返回函数不要引用任何循环变量，或者后续会发生变化的变量。
def count():
    def f(j):
        def g():
            return j * j

        return g

    fs = []
    for i in range(1, 4):
        fs.append(f(i))  # f(i)立刻被执行，因此i的当前值被传入f() 闭包了
    return fs


# 3.匿名函数
# 关键字lambda表示匿名函数，冒号前面的x表示函数参数
# 匿名函数有个限制，就是只能有一个表达式，不用写return，返回值就是该表达式的结果
# 标准格式 lambda：参数：表达式  lambda会返回表达式的结果

print("lambda==", lambda: 3 * 4())  # 返回函数
print("lambda==", (lambda: 3 * 4)())  # 返回表达的结果

# lambda无参数
def build(x, y):
    return lambda: x * x + y * y
# lambda有参数
def lm(x):
    return lambda y,z=4: x * y*z
print(lm(2)(3))
print(lm(2)(3,5))

ld = lambda x: x * x
print(ld(3))


# 4.装饰器（函数功能增强）
def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)

    return wrapper


@log
def now(a):
    print('2015-3-25 %s' % a)


now(5)

#
# def aa1():
#     print("aaaaaaa1")
#
#
# def bb1():
#     print("aaaaaaa1")®
#
#
# def zengqiao(func):
#     def zhuangshi(*a):
#         print("gongnegnzengqiang")
#         return func()
#
#     return zhuangshi()
#
# zengqiao(bb1)
